package qotwReader.parseInput;

import java.io.*;
import java.net.*;

import org.apache.commons.lang.StringEscapeUtils;

import qotwReader.parseInput.exceptions.*;
import qotwReader.types.*;

public class ParseArguments
{
    final private String[] args;
    
    final private EbookType ebook;
    final private DownloadAction download;
    final private ReaderType reader;
    final private File calibreDirectory;
    
    public ParseArguments(String[] args)
        throws UnknownCommandException, UnknownArgumentException, MissingArgumentException, NotDirectoryException
    {
        this.args = args;
                        
        this.ebook = parseEbookType();
        this.reader = parseReaderType();
        this.download = parseDownloadAction();
        this.calibreDirectory = parseCalibreDirectory();
    }
    
    private EbookType parseEbookType()
        throws UnknownCommandException, UnknownArgumentException, MissingArgumentException
    {
        String arg = parseCommandArg(Command.output);
        
        try
        {
            return EbookType.valueOf(arg);
        }
        catch (IllegalArgumentException e)
        {
            throw new UnknownArgumentException(arg, Command.output);
        }
    }
    
    private ReaderType parseReaderType()
        throws UnknownCommandException, UnknownArgumentException, MissingArgumentException
    {
        String arg = parseCommandArg(Command.reader);
        
        try
        {
            return ReaderType.getReaderFromString(arg);
        }
        catch (IllegalArgumentException e)
        {
            throw new UnknownArgumentException(arg, Command.reader);
        }
    }
    
    private DownloadAction parseDownloadAction()
        throws UnknownCommandException, UnknownArgumentException, MissingArgumentException
    {
        String arg = parseCommandArg(Command.download);
        
        try
        {
            URL url = new URL(arg);
            
            DownloadAction dl = DownloadAction.url;
            dl.setUrl(url);
            
            return dl;
        }
        catch (MalformedURLException e)
        {
            try
            {
                return DownloadAction.valueOf(arg);
            }
            catch (IllegalArgumentException e2)
            {
                throw new UnknownArgumentException(arg, Command.download);
            }
        }
    }
    
    private File parseCalibreDirectory()
        throws UnknownCommandException, MissingArgumentException, NotDirectoryException
    {
        String arg = StringEscapeUtils.escapeJava(parseCommandArg(Command.calibredir));
        
        File calibreLoc = new File(arg);
        if (! calibreLoc.isDirectory())
            throw new NotDirectoryException(calibreLoc);
        
        return calibreLoc;
    }
    
    private String parseCommandArg(Command command)
        throws UnknownCommandException, MissingArgumentException
    {        
        for (int i = 0; i < args.length; i += 2)
        {
            String cmd = args[i];
            if (i + 1 >= args.length)
                throw new MissingArgumentException(command.getCommandString());
            
            String arg = args[i + 1];
            
            if (cmd.equalsIgnoreCase(command.getCommandString()))
                return arg;
        }
        
        throw new UnknownCommandException(
                "Tried to find command " + command.toString() + " and it's argument, but could not.\n" +
                "Please make sure to use ALL commands with arguments\n" + 
                "Available commands: \n" +
                Command.getAvailCmdsString()
                );
    }
    
    public ReaderType getReader() { return this.reader; }
    public EbookType getOutputEbook() { return this.ebook; }
    public DownloadAction getDownload() { return this.download; }
    public File getCalibreDirectory() { return this.calibreDirectory; }
}
